package com.fingard.dsp.bank.directbank.crbc01.util;

import javax.crypto.Cipher;
import java.math.BigInteger;
import java.security.KeyFactory;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.NoSuchAlgorithmException;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.RSAPrivateKeySpec;
import java.security.spec.RSAPublicKeySpec;


/**
 * RSA工具类
 *
 */
public class CrbankRsa {

    /**
     * 填充模式
     */
    private static final String CIPHER_MODEL="RSA/ECB/PKCS1Padding";

    private String rsaPrivateKey;
    private String modulus;


    public String getRsaPrivateKey() {
        return rsaPrivateKey;
    }

    public void setRsaPrivateKey(String rsaPrivateKey) {
        this.rsaPrivateKey = rsaPrivateKey;
    }


    private static CrbankRsa crbankRsa=new CrbankRsa();


    public static CrbankRsa getInstance(String modulus, String rsaPrivateKey){
        crbankRsa.modulus = modulus;
        crbankRsa.rsaPrivateKey = rsaPrivateKey;
        return crbankRsa;
    }

    /**
     * 加密
     * @param encrptyStr
     * @param modulus
     * @return
     * @throws Exception
     */
    public static String encrtyByPublicKey(String encrptyStr, String modulus) throws Exception {
        Cipher cipher = Cipher.getInstance(CIPHER_MODEL);
        cipher.init(Cipher.ENCRYPT_MODE, getPublicKey(modulus));
        byte[] enBytes = cipher.doFinal(encrptyStr.getBytes());
        BigInteger bigInteger=new BigInteger(enBytes);
        return bigInteger.toString(16).toUpperCase();
    }


    /**
     * 解密
     * @param decrptyStr
     * @param modulus
     * @param privExponent
     * @return
     * @throws Exception
     */
    public static String decrptyByPrivateKey(String decrptyStr, String modulus, String privExponent) throws Exception {
        Cipher cipher = Cipher.getInstance(CIPHER_MODEL);
        cipher.init(Cipher.DECRYPT_MODE,getPrivateKey(modulus, privExponent));
        return new String(cipher.doFinal(new BigInteger(decrptyStr,16).toByteArray()));
    }

    /**
     * 获取公钥
     * @param modulus
     * @return
     */
    public static RSAPublicKey getPublicKey(String modulus){
        KeyFactory kf;
        RSAPublicKey publicKey=null;
        try {
            kf = KeyFactory.getInstance("RSA");
            RSAPublicKeySpec spec = new RSAPublicKeySpec(new BigInteger(modulus, 16), new BigInteger("10001", 16));
            publicKey=(RSAPublicKey)kf.generatePublic(spec);
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (InvalidKeySpecException e) {
            e.printStackTrace();
        }
        return publicKey;
    }


    /**
     * 获取私钥
     * @param modulus
     * @return
     */
    public static RSAPrivateKey getPrivateKey(String modulus, String privExponent){
        KeyFactory kf;
        RSAPrivateKey privateKey=null;
        try {
            kf = KeyFactory.getInstance("RSA");
            RSAPrivateKeySpec spec = new RSAPrivateKeySpec(new BigInteger(modulus, 16), new BigInteger(privExponent, 16));
            privateKey=(RSAPrivateKey)kf.generatePrivate(spec);
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (InvalidKeySpecException e) {
            e.printStackTrace();
        }
        return privateKey;
    }




    /**
     * 生成RSAkey信息
     */
    public static KeyPair generateRSAKey() {
        KeyPairGenerator keyPairGen;
        KeyPair keyPair = null;
        try {
            keyPairGen = KeyPairGenerator.getInstance("RSA");
            // 密钥位数
            keyPairGen.initialize(1024);
            // 密钥对
            keyPair = keyPairGen.generateKeyPair();

        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        }
        return keyPair;
    }
}
